package com.sun.impls.users;

import cn.dev33.satoken.secure.SaSecureUtil;
import cn.dev33.satoken.stp.StpUtil;
import cn.dev33.satoken.stp.parameter.SaLoginParameter;
import cn.dev33.satoken.util.SaResult;
import cn.hutool.core.util.StrUtil;
import com.sun.dto.PagedList;
import com.sun.dto.users.UserSearchDto;
import com.sun.entity.users.Role;
import com.sun.entity.users.User;
import com.sun.impls.BaseService;
import com.sun.repository.users.UserRepository;
import com.sun.services.CustomPredicate;
import com.sun.services.users.UserService;
import com.sun.utils.Constant;
import jakarta.persistence.EntityManager;
import jakarta.persistence.PersistenceContext;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.Predicate;
import jakarta.persistence.criteria.Root;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.web.bind.annotation.RequestParam;

import java.util.List;

/**
 * 用户服务实现类，提供用户相关的业务逻辑实现
 */
@Service
public class UserServiceImpl extends BaseService implements UserService {
    @Autowired
    private UserRepository userRepository;
    @Autowired
    private RedisTemplate<String, Object> redisTemplate;
    @PersistenceContext
    private EntityManager em;

    /**
     * 用户登录
     *
     * @param username 用户名
     * @param password 密码
     * @return 登录结果
     */
    @Override
    public SaResult login(String username, String password) {
        User user = userRepository.findUserByUsername(username);
        if (user == null) {
            return SaResult.error("用户不存在");
        }
        if (!user.getPassword().equals(SaSecureUtil.sha256(password))) {
            return SaResult.error("密码错误");
        }
        StpUtil.login(user.getId(), new SaLoginParameter()
                .setExtra("name", user.getName())
                .setExtra("roles", user.getRoles().stream().map(Role::getName).toList())
                .setExtra("phone", user.getPhone())
                .setExtra("openid", user.getOpenid())
        );
        return SaResult.ok("登录成功").setData(StpUtil.getTokenInfo());
    }

    @Override
    public SaResult ReloadUserRole(Long id) {
        User user = userRepository.findById(id).orElse(null);
        if (user == null) {
            return SaResult.error("用户不存在");
        }
        ;
        List<String> roles = user.getRoles().stream().map(Role::getName).toList();
        String key = Constant.REDIS_USER_ROLE_PREFIX + id;
        redisTemplate.opsForValue().set(key, roles);
        return SaResult.ok();

    }

    /**
     * 创建用户
     *
     * @param user 用户信息
     * @return 创建结果
     */
    @Override
    public SaResult createUser(User user) {
        if (userRepository.findUserByUsername(user.getUsername()) != null) {
            return SaResult.error("用户名已存在");
        }
        user.setId(nextId());
        if (!StrUtil.isEmpty(user.getPassword())) {
            user.setPassword(SaSecureUtil.sha256(user.getPassword()));
        }
        userRepository.save(user);
        return SaResult.ok().setMsg("用户创建成功");
    }

    @Override
    public SaResult DeleteUser(List<Long> ids) {
        if (ids == null || ids.isEmpty()) {
            return SaResult.error("用户ID列表不能为空");
        }
        try {
            userRepository.deleteAllById(ids);
            return SaResult.ok("用户标记删除成功");
        } catch (Exception e) {
            e.printStackTrace();
            return SaResult.error("标记删除用户失败: " + e.getMessage());
        }
    }

    @Override
    public SaResult UpdateUser(User user) {
        if (user == null || user.getId() == null) {
            return SaResult.error("用户信息或ID不能为空");
        }
        try {
            User existingUser = userRepository.findById(user.getId()).orElse(null);
            if (existingUser == null) {
                return SaResult.error("用户不存在");
            }
            // 其他字段根据需要更新
            userRepository.save(user);
            return SaResult.ok("用户信息更新成功");
        } catch (Exception e) {
            return SaResult.error("更新用户信息失败: " + e.getMessage());
        }
    }

    @Override
    public List<User> getUserList(UserSearchDto userSearchDto) {
        CustomPredicate<User> predicate = (cb, root) -> getPredicates(cb, root, userSearchDto);
        return getList(User.class, predicate, userSearchDto);
    }

    @Override
    public PagedList<User> getUserPageList( UserSearchDto searchDto) {
        CustomPredicate<User> predicate = (cb, root) -> getPredicates(cb, root, searchDto);
        return getPagedList(User.class, predicate, searchDto);
    }

    private <T> List<Predicate> getPredicates(CriteriaBuilder cb, Root<T> root, UserSearchDto searchDto) {
        List<Predicate> where = basePredicates(cb, root, searchDto);
        if (!StrUtil.isEmpty(searchDto.getUsername())) {
            where.add(cb.equal(root.get("username"), searchDto.getUsername()));
        }
        if (!StrUtil.isEmpty(searchDto.getNickname())) {
            where.add(cb.like(root.get("nickname"), searchDto.getNickname()));
        }
        if (!StrUtil.isEmpty(searchDto.getEmail())) {
            where.add(cb.equal(root.get("email"), searchDto.getEmail()));
        }
        if (!StrUtil.isEmpty(searchDto.getAvatar())) {
            where.add(cb.equal(root.get("avatar"), searchDto.getAvatar()));
        }
        if (!StrUtil.isEmpty(searchDto.getPhone())) {
            where.add(cb.equal(root.get("phone"), searchDto.getPhone()));
        }
        if (!StrUtil.isEmpty(searchDto.getOpenid())) {
            where.add(cb.equal(root.get("openId"), searchDto.getPhone()));
        }
        return where;
    }


}
